#include <iostream>
#include <string>
#include <unistd.h>
#include <vector>
#include "Thread.hpp"
#include "LockGuard.hpp"

using namespace ThreadMoudle;

// // 模拟抢票 10000张
// int tickets = 10000; // 共享资源，造成数据不一致问题

// // 全局或者静态只需INIT，无需destory
// pthread_mutex_t gmutex = PTHREAD_MUTEX_INITIALIZER;

// void route(const std::string &name)
// {
//     while (true)
//     {
//         pthread_mutex_lock(&gmutex); // 上锁
//         // 有票才抢
//         if (tickets > 0)
//         {
//             usleep(1000); // 1ms -> 抢票花费时间
//             printf("who: %s, get a ticket: %d\n", name.c_str(), tickets);
//             tickets--;
//             pthread_mutex_unlock(&gmutex); // 解锁
//         }
//         else
//         {
//             pthread_mutex_unlock(&gmutex); // 退出循环之前解锁，否则会阻塞
//             break;
//         }
//     }
// }

// static int threadnum = 4;

// int main()
// {
//     std::vector<Thread> threads;
//     // 1.创建线程
//     for (int i = 0; i < threadnum; i++)
//     {
//         std::string name = "thread-" + std::to_string(i + 1);
//         threads.emplace_back(name, route);
//     }

//     // 2.启动线程
//     for (auto &thread : threads)
//     {
//         thread.Start();
//     }

//     // 3.终止线程
//     for (auto &thread : threads)
//     {
//         thread.Join();
//     }
//     return 0;
// }

// // 模拟抢票 10000张
// int tickets = 10000; // 共享资源，造成数据不一致问题

// void route(ThreadData* td)
// {
//     while (true)
//     {
//         pthread_mutex_lock(td->_lock); // 上锁
//         // 有票才抢
//         if (tickets > 0)
//         {
//             usleep(1000); // 1ms -> 抢票花费时间
//             printf("who: %s, get a ticket: %d\n", td->_name.c_str(), tickets);
//             tickets--;
//             pthread_mutex_unlock(td->_lock); // 解锁
//         }
//         else
//         {
//             pthread_mutex_unlock(td->_lock); // 退出循环之前解锁，否则会阻塞
//             break;
//         }
//     }
// }

// static int threadnum = 4;

// int main()
// {
//     pthread_mutex_t mutex; // 局部锁，需要init和destory
//     pthread_mutex_init(&mutex, nullptr);

//     std::vector<Thread> threads;
//     // 1.创建线程
//     for (int i = 0; i < threadnum; i++)
//     {
//         std::string name = "thread-" + std::to_string(i + 1);
//         ThreadData *td = new ThreadData(name, &mutex); // new一个Thread对象，传局部锁
//         threads.emplace_back(name, route,td);
//     }

//     // 2.启动线程
//     for (auto &thread : threads)
//     {
//         thread.Start();
//     }

//     // 3.终止线程
//     for (auto &thread : threads)
//     {
//         thread.Join();
//     }

//     pthread_mutex_destroy(&mutex);

//     return 0;
// }


// 3.RAII
int tickets = 10000; // 共享资源，造成数据不一致问题

void route(ThreadData* td)
{
    while (true)
    {
        LockGuard lockguard(td->_lock); // RAII锁风格
        // 有票才抢
        if (tickets > 0)
        {
            usleep(1000); // 1ms -> 抢票花费时间
            printf("who: %s, get a ticket: %d\n", td->_name.c_str(), tickets);
            tickets--;
        }
        else
        {
            break;
        }
    }
}

static int threadnum = 4;

int main()
{
    pthread_mutex_t mutex; // 局部锁，需要init和destory
    pthread_mutex_init(&mutex, nullptr);

    std::vector<Thread> threads;
    // 1.创建线程
    for (int i = 0; i < threadnum; i++)
    {
        std::string name = "thread-" + std::to_string(i + 1);
        ThreadData *td = new ThreadData(name, &mutex); // new一个Thread对象，传局部锁
        threads.emplace_back(name, route,td);
    }

    // 2.启动线程
    for (auto &thread : threads)
    {
        thread.Start();
    }

    // 3.终止线程
    for (auto &thread : threads)
    {
        thread.Join();
    }

    pthread_mutex_destroy(&mutex);

    return 0;
}